/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import type {JSX, ChangeEvent} from 'react';
import { useRef, useState } from 'react';

import LexicalEditor, { LexicalEditorRef } from './LexicalEditor';

console.warn(
  'If you are profiling the playground app, please ensure you turn off the debug view. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.',
);

function App(): JSX.Element {
  const editorRef = useRef<LexicalEditorRef>(null);
  const [isPreviewMode, setIsPreviewMode] = useState(false);
  const [uploading, setUploading] = useState(false);
  const fileInputRef = useRef<HTMLInputElement | null>(null);

  // Example usage of the editor methods
  const handleGetJSON = () => {
    const jsonData = editorRef.current?.getJSON();
    console.log('JSON Data:', jsonData);
  };

  const handleLoadJSON = () => {
    // Example JSON data - you can replace this with your own
    const exampleJSON: any = {
      root: {
        children: [
          {
            children: [
              {
                detail: 0,
                format: 0,
                mode: "normal",
                style: "",
                text: "Hello from loaded JSON!",
                type: "text",
                version: 1
              }
            ],
            direction: "ltr" as const,
            format: "",
            indent: 0,
            type: "paragraph",
            version: 1
          }
        ],
        direction: "ltr" as const,
        format: "",
        indent: 0,
        type: "root",
        version: 1
      }
    };
    editorRef.current?.loadJSON(exampleJSON);
  };

  const handleGetHTML = () => {
    const htmlData = editorRef.current?.getHTML();
    console.log('HTML Data:', htmlData);
  };

  // 点击按钮 -> 触发文件选择
  const handleLoadHTML = () => {
    if (uploading) return;
    fileInputRef.current?.click();
  };

  // 将完整HTML注入编辑器（优先模拟粘贴，保持更多格式）
  const injectHtmlToEditor = async (fullHTML: string) => {
    try {
      const parser = new DOMParser();
      const doc = parser.parseFromString(fullHTML, 'text/html');
      const bodyHTML = doc.body?.innerHTML || fullHTML;

      const editorElement = document.querySelector('[contenteditable="true"]');
      if (editorElement) {
        (editorElement as HTMLElement).focus();

        // 过滤潜在危险标签
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = bodyHTML;
        tempDiv.querySelectorAll('script, meta, link').forEach(el => el.remove());
        const safeHTML = tempDiv.innerHTML;

        const dataTransfer = new DataTransfer();
        dataTransfer.setData('text/html', safeHTML);
        dataTransfer.setData('text/plain', tempDiv.innerText || '');
        const pasteEvent = new ClipboardEvent('paste', {
          bubbles: true,
          cancelable: true,
          clipboardData: dataTransfer,
        });
        editorElement.dispatchEvent(pasteEvent);
        console.log('已通过模拟粘贴注入HTML');
      } else {
        console.warn('未找到编辑器DOM，降级使用 loadHTML');
        editorRef.current?.loadHTML(bodyHTML);
      }
    } catch (e) {
      console.error('注入HTML失败，降级 loadHTML:', e);
      editorRef.current?.loadHTML(fullHTML);
    }
  };

  // 处理文件选择与上传
  const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true);
    try {
      const formData = new FormData();
      formData.append('file', file);
      console.log('开始上传并转换:', file.name);
      const res = await fetch('/api/convert-to-html', { method: 'POST', body: formData });
      if (!res.ok) {
        throw new Error(`HTTP ${res.status}`);
      }
      const data = await res.json();
      if (!data.success) {
        throw new Error(data.error || '转换失败');
      }
      const fullHTML: string = data.htmlContent;
      console.log('转换成功，开始注入编辑器');
      await injectHtmlToEditor(fullHTML);
    } catch (err) {
      console.error('文件上传/转换失败:', err);
      editorRef.current?.loadHTML(`<h2>转换失败</h2><p>${(err as Error).message}</p>`);
    } finally {
      setUploading(false);
      if (fileInputRef.current) fileInputRef.current.value = '';
    }
  };

  const handleClear = () => {
    editorRef.current?.clear();
  };

  const handleDataChange = (data: any) => {
    console.log('Editor data changed:', data);
  };

  const handleTogglePreviewMode = () => {
    const newPreviewMode = !isPreviewMode;
    setIsPreviewMode(newPreviewMode);
    editorRef.current?.setPreviewMode(newPreviewMode);
  };

  return (
    <div>
      {/* Control buttons for demonstration */}
      <div style={{ padding: '10px' }}>
        <button onClick={handleGetJSON} style={{ margin: '5px' }}>
          Get JSON
        </button>
        <button onClick={handleLoadJSON} style={{ margin: '5px' }}>
          Load JSON
        </button>
        <button onClick={handleGetHTML} style={{ margin: '5px' }}>
          Get HTML
        </button>
        <button
          onClick={handleLoadHTML}
          style={{ margin: '5px' }}
          disabled={uploading}
        >
          {uploading ? '上传中...' : '上传文件'}
        </button>
        <input
           ref={fileInputRef}
            type="file"
            style={{ display: 'none' }}
            accept=".doc,.docx,.pdf,.html,.htm,.md,.txt,.ppt,.pptx"
            onChange={handleFileChange}
        />
        <button onClick={handleClear} style={{ margin: '5px' }}>
          Clear
        </button>
        <button 
          onClick={handleTogglePreviewMode} 
          style={{ 
            margin: '5px',
            backgroundColor: isPreviewMode ? '#dc3545' : '#6c757d',
            color: 'white'
          }}
        >
          {isPreviewMode ? '退出预览' : '预览模式'}
        </button>
      </div>
      
      <LexicalEditor
        ref={editorRef}
        dataType="json"
        onDataChange={handleDataChange}
      />
    </div>
  );
}

export default function PlaygroundApp(): JSX.Element {
  return <App />;
}